/* -----------------------------------------------------------------------------
 * PROJECT    : lwf_handlers
 * FILE       : SimpleFractionHandler.java
 *
 * HISTORY:
 * Date          Author                        Description
 * ----------------------------------------------------------------------------- 
 * Mar 12, 2011  mycodetalks			       Created
 */
package net.lwf.handler.math.fraction;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import lwf.handler.IProcessHandler;
import lwf.handler.ProcessHandler;
import lwf.handler.entities.RadioData;
import lwf.handler.helper.DisplayFormatter;
import net.lwf.color.util.ColorUtil;
import net.lwf.common.constant.ICommonConstant;
import net.lwf.entity.QuestionInfo;
import net.lwf.jaxb.entity.Fraction;
import net.lwf.jaxb.util.maths.fraction.FractionGenerator;
import net.lwf.pdf.util.FontUtil;
import net.lwf.pdf.util.PdfPCellUtil;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;

/**
 * Class description goes here
 */
public class SimpleFractionHandler extends ProcessHandler implements IProcessHandler {
	
	private FractionGenerator generator;
	
	public SimpleFractionHandler(String grade, String operation) {
		this.generator = new FractionGenerator(grade, operation);
	}

	@Override
	public List<QuestionInfo> generateMultiple() {
		List<QuestionInfo> questions = new ArrayList<QuestionInfo>();
		int nQuestions = getRows() * getColumns();
		for(int i=0; i<nQuestions; i++) {
			QuestionInfo question = generateSingle(true);
			question.setQuestionNumber(i+1);
			questions.add(question);
		}
		return questions;
	}

	@Override
	public QuestionInfo generateSingle() {
		return this.generateSingle(false);
	}

	@Override
	public int getColumns() {
		return 1;
	}

	@Override
	public void getContent(Document document) throws DocumentException {
	}

	@Override
	public String getPdfInstructionalText() {
		return "Write the fraction that is represented by the shaded area.";
	}

	@Override
	public String getPdfNote() {
		return null;
	}

	@Override
	public int getRows() {
		return 15;
	}

	@Override
	public boolean isPortrait() {
		return true;
	}

	public DisplayFormatter getDisplayFormatter() {
		return null;
	}

	public String getQuestionDesc() {
		return null;
	}
	
	public Element processCellData(QuestionInfo question) {
		
		Fraction fraction = (Fraction) question.getQuestionObject();
		PdfPTable table = new PdfPTable(2);
		float[] colsWidth = {4f, 1f}; // Code 1
		try {
			table.setWidths(colsWidth);
		} catch (DocumentException e) {
			e.printStackTrace();
		}
        table.setSpacingBefore(20);

        //Row 1
        PdfPCell cell;
        cell = new PdfPCell(new Phrase("# " + question.getQuestionNumber(), FontUtil.getQuestionNumberFont()));
        cell.setBorder(0);
        cell.setColspan(2);

        table.addCell(cell);
        
        //row 2
        //Cell 1
        cell = this.generatePdfQuestion(fraction);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setBorder(0);
        table.addCell(cell);
        //Cell 2
        table.addCell(PdfPCellUtil.getEmptyCell());

        //Row 3
        table.addCell(PdfPCellUtil.getEmptyCell(2));
        
        table.completeRow();

		return table;
	}
	
	private PdfPCell generatePdfQuestion(Fraction fraction) {
		int denominator = fraction.getDenominator();
		PdfPTable table = new PdfPTable(denominator);

		for(int i=0; i<denominator; i++) {
			PdfPCell cell = new PdfPCell(new Phrase(" "));
			if(i+1 <= fraction.getNumerator()) {
				cell.setBackgroundColor(BaseColor.GRAY);
			}
			else {
				cell.setBackgroundColor(BaseColor.WHITE);
			}
			table.addCell(cell);
		}

		return new PdfPCell(table);
		
	}
	
	private QuestionInfo generateSingle(boolean isMultiple) {
		QuestionInfo qinfo = new QuestionInfo();
		qinfo.setOperation("simple");
		Fraction fraction = this.generator.generate(false);
		qinfo.setQuestionObject(fraction);
		qinfo.setAnswer(fraction.toString());
		if(!isMultiple) {
			qinfo.setHtmlQuestion(this.generateHtmlQuestion(fraction));	
			qinfo.setRadioAnswerChoices(this.generateAnswerChoices(fraction.toString()));
		}
		
		return qinfo;		
	}
	
	private String generateHtmlQuestion(Fraction fraction) {
		StringBuffer sbHtml = new StringBuffer("<table align=\"center\" border=\"1\" cellpadding=\"0\" cellspacing=\"0\" >");
		sbHtml.append("<tr>");
		int denominator = fraction.getDenominator();
		String color = ColorUtil.getColorCode();
		while(color.equals(ICommonConstant.WHITE_COLOR)) {
			color = ColorUtil.getColorCode();
		}
		for(int i=0; i<denominator; i++) {
			if(i+1 <= fraction.getNumerator()) {
				sbHtml.append("<td class=\"fractionbox\" bgcolor=\"" + color + "\" > &nbsp; </td>");
			}
			else {
				sbHtml.append("<td class=\"fractionbox\"> &nbsp; </td>");
			}
		}
		sbHtml.append("</tr>");
		sbHtml.append("</table>");
		
		return sbHtml.toString();
		
	}
	
	private List<RadioData> generateAnswerChoices(String answer) {
		Map<String, String> multiples = this.generator.generateMultiple(true, 4);
		boolean skipOne = false;
		if(multiples.containsKey(answer)) {
			multiples.remove(answer);
		}
		else {
			skipOne = true;
		}

		List<RadioData> choices = new ArrayList<RadioData>();
		RadioData data = null;
		Iterator<Entry<String, String>> iterator = multiples.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry<String, String> mapentry = iterator.next();
			if(skipOne) {
				skipOne = false;
			}
			else {
				data = new RadioData(mapentry.getValue(), mapentry.getValue());
				choices.add(data);
			}
		}
		data = new RadioData(answer, answer);
		choices.add(data);
		Collections.shuffle(choices);
		return choices;
	}

}



